package org.vacoor.nothing.security;

import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.ProtocolHandler;
import org.apache.coyote.http11.Http11AprProtocol;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.coyote.http11.Http11Protocol;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

/**
 */
public class TomcatInfo {
    /*
    // encode right
    if has utf8 && utf8 value = "✓" (10003)
        return;
    // decode error, server is not utf8 or client is not utf8
    qsBytes = queryString.hex -> bytes

    get server uri encoding
    clientSubmitBytes = param.getBytes(server uri encoding)

    1003Bytes
    detect client uri encoding
    ...

     */
    // http://wiki.eclipse.org/Jetty/Howto/International_Characters#Characters_included_in_HTTP_requests
    // first Request.setQueryEncoding(String)
    // second:
    //    System Property
    //    jetty6: org.mortbay.util.URI.charset
    //    jetty7: org.eclipse.jetty.util.URI.charset

    // jboss
    // System.property org.apache.catalina.connector.URI_ENCODING

    /*
    public void getServerInfo(ServletContext context) {
        String serverInfo = context.getServerInfo();
        if (null != serverInfo) {
            serverInfo = serverInfo.toLowerCase();
            if (-1 < serverInfo.indexOf("tomcat")) {

            }
            if (-1 < serverInfo.indexOf("jetty")) {

            }
        }

        throw new RuntimeException();
    }
    */

    public void getConnectorInfo() {
        Server server = getServer();
        Service[] services = server.findServices();
        for (Service service : services) {
            for (Connector connector : service.findConnectors()) {
                ProtocolHandler protocolHandler = connector.getProtocolHandler();
                if (protocolHandler instanceof Http11Protocol
                        || protocolHandler instanceof Http11AprProtocol
                        || protocolHandler instanceof Http11NioProtocol) {
                    int serverPort = connector.getPort();
                    String uriEncoding = connector.getURIEncoding();
                    System.out.println("HTTP Port: " + connector.getPort());
                }
            }
        }
    }

    public Server getServer() {
        try {
            // tomcat 6-
            Class<?> clazz = Class.forName("org.apache.catalina.ServerFactory");
            return (Server) clazz.getMethod("getServer", new Class<?>[0]).invoke(null, new Object[0]);
        } catch (ClassNotFoundException ignore) {
        } catch (InvocationTargetException ignore) {
        } catch (NoSuchMethodException ignore) {
        } catch (IllegalAccessException ignore) {
        }

        // tomcat 7+
        List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
        MBeanServer mBeanServer = 0 < servers.size() ? servers.get(0) : ManagementFactory.getPlatformMBeanServer();
        try {
            // new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
            return (Server) mBeanServer.getAttribute(new ObjectName("Catalina", "type", "Server"), "managedResource");
        } catch (Exception ignore) {
        }
        // embedded  tomcat 7+
        try {
            return (Server) mBeanServer.getAttribute(new ObjectName("Tomcat", "type", "Server"), "managedResource");
        } catch (Exception ignore) {
        }

        throw new IllegalStateException("can't find catalina server instance.");
    }
}
